/**
 * 同步滚动甘特图组件
 *
 * 功能说明：
 * 1. 酒店房间状态的可视化管理界面
 * 2. 支持Canvas 2D高性能渲染
 * 3. 提供拖拽、多选、悬停等交互功能
 * 4. 集成状态管理、右键菜单、批量操作等功能
 * 5. 支持同步滚动和响应式布局
 *
 * 技术特点：
 * - Canvas 2D API 高性能渲染
 * - 双缓冲渲染优化
 * - 精细化防抖和RAF优化
 * - 模块化Hook设计
 * - 类型安全的TypeScript
 */

import React, {
  useRef,
  useEffect,
  useState,
  useCallback,
  useMemo,
} from 'react';

// ========== 类型导入 ==========
import { RoomType, RoomStatus } from '../../../types/room';
import type { Room, RoomAvailability } from '../../../types/room';

// ========== 组件导入 ==========
import ContextMenu from './ContextMenu';
import DragPreview from './DragPreview';
import StatusSelector from './StatusSelector';
import StateManagerDebugPanel from './StateManagerDebugPanel';
import BatchOperationMenu, { type BatchOperation } from './BatchOperationMenu';
import OrderDrawer from './OrderDrawer';
import SimpleMergePanel from './SimpleMergePanel';
import TimeAxisSelector from './TimeAxisSelector';
import StatusWorkflow from './StatusWorkflow';
import EnhancedDragPreview from './EnhancedDragPreview';
import DragOperationFeedback, {
  useDragOperationFeedback,
} from './DragOperationFeedback';
import DragStatusNotification from './DragStatusNotification';
import BatchDragVisualizer from './BatchDragVisualizer';
import LongPressIndicator from './LongPressIndicator';
import BatchDragToolbar from './BatchDragToolbar';

// ========== Hook导入 ==========
import { useOptimizedRoomData } from '../hooks/useOptimizedRoomData';
import { useHoverEffect } from '../hooks/useHoverEffect';
import { useContextMenu } from '../hooks/useContextMenu';
import { useDragDrop } from '../hooks/useDragDrop';
import { useMultiSelection } from '../hooks/useMultiSelection';
import { useRoomStateManager } from '../hooks/useRoomStateManager';
import { useBatchOperations } from '../hooks/useBatchOperations';
import useSimpleMerge from '../hooks/useSimpleMerge';
import { useBatchDragDrop } from '../hooks/useBatchDragDrop';
import { useLongPressDrag } from '../hooks/useLongPressDrag';
import { useTimeAxisConfig } from '../hooks/useTimeAxisConfig';

// ========== 工具类导入 ==========
import { performanceUtils } from '../utils/PerformanceMonitor';
import { RoomStatusManager } from '../utils/RoomStatusManager';

// ========== 类型导入 ==========
import type { OrderFormData } from './OrderDrawer';

// ========== 样式导入 ==========
import styles from '../styles/SimpleCanvasGantt.module.css';

// ========== 组件接口定义 ==========

/**
 * 同步滚动甘特图组件属性接口
 */
interface SyncScrollGanttChartProps {
  rooms?: Room[]; // 房间数据数组
  availabilities?: RoomAvailability[]; // 房间可用性数据数组
  onRoomSelect?: (roomId: string, date: string) => void; // 房间选择回调
  onNewOrder?: (roomId: string, date: string) => void; // 新建订单回调
}

// ========== 常量定义 ==========

/**
 * 房间类型标签映射
 * 将房间类型枚举转换为中文显示标签
 */
const roomTypeLabels = {
  [RoomType.STANDARD_SINGLE]: '标准单人间',
  [RoomType.DELUXE_KING]: '豪华大床房',
  [RoomType.EXECUTIVE_SUITE]: '行政套房',
  [RoomType.ALL]: '所有房型',
};

// ========== 工具函数 ==========

/**
 * 简单的伪随机数生成器
 * 使用固定种子确保数据稳定性，避免每次刷新数据变化
 * @param seed 随机数种子
 * @returns 0-1之间的伪随机数
 */
const seededRandom = (seed: number) => {
  const x = Math.sin(seed) * 10000;
  return x - Math.floor(x);
};

/**
 * 生成符合业务逻辑的模拟数据
 * 使用固定种子确保数据不变，生成真实的酒店业务场景数据
 * @param dates 日期数组
 * @returns 房间可用性数据数组
 */
const generateMockAvailabilities = (dates: string[]): RoomAvailability[] => {
  const availabilities: RoomAvailability[] = [];
  const today = new Date();
  // 获取今天的 MM/DD 格式，与dates数组格式一致
  const todayMonth = String(today.getMonth() + 1).padStart(2, '0');
  const todayDay = String(today.getDate()).padStart(2, '0');
  const todayString = `${todayMonth}/${todayDay}`;

  // 找到今天在dates数组中的索引
  const todayIndex = dates.indexOf(todayString);
  console.log('今天日期:', todayString, '索引:', todayIndex);

  // 使用固定种子替换Math.random()
  let seedCounter = 12345; // 固定种子起始值

  // 为每个房间生成合理的预订数据
  for (let roomIndex = 1; roomIndex <= 15; roomIndex++) {
    const roomId = `room-${roomIndex}`;

    // 每个房间有40%概率有预订（酒店业务相对稳定）
    if (seededRandom(seedCounter++) < 0.4) {
      // 生成预订时间段
      const startDateIndex = Math.floor(
        seededRandom(seedCounter++) * (dates.length - 3)
      );
      const duration = Math.floor(seededRandom(seedCounter++) * 3) + 1; // 1-3天的预订

      for (let day = 0; day < duration; day++) {
        const dateIndex = startDateIndex + day;
        if (dateIndex >= dates.length) break;

        const currentDate = dates[dateIndex];
        let status: RoomStatus;

        // 根据日期索引和今天的关系确定状态
        if (dateIndex < todayIndex) {
          // 过去的日期
          if (day === duration - 1) {
            // 最后一天，已退房或需要清洁
            status =
              seededRandom(seedCounter++) < 0.7
                ? RoomStatus.CHECKED_OUT
                : RoomStatus.DIRTY;
          } else {
            // 中间日期，已入住
            status = RoomStatus.OCCUPIED;
          }
        } else if (dateIndex === todayIndex) {
          // 今天
          if (day === 0) {
            // 今天入住
            status =
              seededRandom(seedCounter++) < 0.8
                ? RoomStatus.OCCUPIED
                : RoomStatus.BOOKED;
          } else if (day === duration - 1) {
            // 今天退房
            status = RoomStatus.CHECKED_OUT;
          } else {
            status = RoomStatus.OCCUPIED;
          }
        } else {
          // 未来的日期 - 预订状态
          if (seededRandom(seedCounter++) < 0.9) {
            status = RoomStatus.BOOKED;
          } else {
            status = RoomStatus.VIP_BOOKED;
          }
        }

        availabilities.push({
          roomId,
          month: currentDate,
          status,
        });
      }
    }
  }

  // 添加一些基于今天的维护和清洁状态示例
  if (todayIndex >= 0) {
    const maintenanceExamples = [
      { roomId: 'room-3', dateOffset: 0, status: RoomStatus.MAINTENANCE }, // 今天维修
      { roomId: 'room-7', dateOffset: 1, status: RoomStatus.CLEANING }, // 明天清洁
      { roomId: 'room-12', dateOffset: -1, status: RoomStatus.CLEANED }, // 昨天清洁完成
      { roomId: 'room-8', dateOffset: 2, status: RoomStatus.REPAIR }, // 后天维修
    ];

    // 添加维护示例
    maintenanceExamples.forEach(example => {
      const targetIndex = todayIndex + example.dateOffset;
      if (targetIndex >= 0 && targetIndex < dates.length) {
        const targetDate = dates[targetIndex];

        // 检查该房间该日期是否已有状态
        const existingAvailability = availabilities.find(
          av => av.roomId === example.roomId && av.month === targetDate
        );

        if (!existingAvailability) {
          availabilities.push({
            roomId: example.roomId,
            month: targetDate,
            status: example.status,
          });
        }
      }
    });
  }

  return availabilities;
};

// 模拟数据 - 按房型分组
const generateRoomsByType = () => {
  const rooms: Room[] = [];

  // 房型配置：房型、数量、起始价格、分组标题
  const roomTypeConfigs = [
    {
      type: RoomType.STANDARD_SINGLE,
      count: 6,
      basePrice: 168,
      prefix: '标准',
      groupName: '📍 标准单人间区域',
    },
    {
      type: RoomType.DELUXE_KING,
      count: 5,
      basePrice: 288,
      prefix: '豪华',
      groupName: '🏨 豪华大床房区域',
    },
    {
      type: RoomType.EXECUTIVE_SUITE,
      count: 4,
      basePrice: 488,
      prefix: '套房',
      groupName: '✨ 行政套房区域',
    },
  ];

  let roomIndex = 1;

  roomTypeConfigs.forEach((config, typeIndex) => {
    for (let i = 0; i < config.count; i++) {
      const building = typeIndex + 1; // 不同房型在不同楼栋
      const floor = Math.floor(i / 3) + 1; // 每3间房一层
      const roomInFloor = (i % 3) + 1; // 楼层内的房间号

      rooms.push({
        id: `room-${roomIndex}`,
        building: `${building}号楼`,
        roomNumber: `${building}${String(floor).padStart(1, '0')}0${roomInFloor}`, // 例：1101, 1102, 1103
        roomType: config.type,
        floor: floor,
        price: config.basePrice + i * 20, // 同类型房间价格略有差异
      });

      roomIndex++;
    }
  });

  return rooms;
};

const mockRooms: Room[] = generateRoomsByType();

/**
 * 同步滚动甘特图组件
 * 酒店房间状态管理的核心组件
 *
 * @param rooms 房间数据数组，默认为模拟数据
 * @param availabilities 房间可用性数据数组
 * @param onRoomSelect 房间选择回调函数
 * @param onNewOrder 新建订单回调函数
 */
const SyncScrollGanttChart: React.FC<SyncScrollGanttChartProps> = ({
  rooms = mockRooms,
  availabilities = [],
  onRoomSelect,
  onNewOrder,
}) => {
  // ========== Canvas引用 ==========

  /**
   * 主Canvas引用
   * 用于绘制甘特图的内容区域
   */
  const canvasRef = useRef<HTMLCanvasElement>(null);

  /**
   * 表头Canvas引用
   * 用于绘制同步滚动的表头
   */
  const headerCanvasRef = useRef<HTMLCanvasElement>(null);

  /**
   * 表头容器引用
   * 用于控制表头的显示和滚动
   */
  const headerContainerRef = useRef<HTMLDivElement>(null);

  /**
   * 主容器引用
   * 用于控制整个甘特图的布局和滚动
   */
  const containerRef = useRef<HTMLDivElement>(null);

  // ========== Hook使用 ==========

  /**
   * 时间轴配置Hook
   * 管理日期范围、时间轴状态等配置
   */
  const {
    timeAxisState,
    dates: timeAxisDates,
    dateInfos: timeAxisDateInfos,
    changeView,
    changeRange,
    setQuickRange,
    navigateTime,
  } = useTimeAxisConfig('day');

  // 日期导航函数 - 使用内置的navigateTime
  const navigateDateRange = useCallback(
    (direction: 'prev' | 'next') => {
      console.log(`📅 开始${direction === 'prev' ? '向前' : '向后'}导航`);
      try {
        navigateTime(direction);
        console.log('📅 导航完成');
      } catch (error) {
        console.error('导航失败:', error);
      }
    },
    [navigateTime]
  );

  // 调试面板状态
  const [showDebugPanel, setShowDebugPanel] = useState<boolean>(false);
  const [useEnhancedDrag, setUseEnhancedDrag] = useState(true);

  // 批量操作菜单状态
  const [showBatchMenu, setShowBatchMenu] = useState<boolean>(false);

  // 新增订单抽屉状态
  const [showOrderDrawer, setShowOrderDrawer] = useState<boolean>(false);
  const [selectedCellForOrder, setSelectedCellForOrder] = useState<{
    roomId: string;
    date: string;
  } | null>(null);

  // 合并面板状态
  const [showMergePanel, setShowMergePanel] = useState<boolean>(false);

  // 使用时间轴配置的日期数据
  const dateAxisData = useMemo(
    () => ({
      dates: timeAxisDates,
      dateInfos: timeAxisDateInfos,
      effectiveDays: timeAxisState.dateRange,
    }),
    [timeAxisDates, timeAxisDateInfos, timeAxisState.dateRange]
  );

  // 生成模拟数据
  const mockAvailabilitiesWithDates = useMemo(() => {
    return generateMockAvailabilities(dateAxisData.dates);
  }, [dateAxisData.dates]);

  // 使用高性能状态管理器
  const stateManager = useRoomStateManager();

  // 使用批量操作Hook
  const batchOperations = useBatchOperations();

  // 合并数据 - 状态管理器数据优先级最高
  const allAvailabilities = useMemo(() => {
    // 先合并基础数据
    const baseData = [...availabilities, ...mockAvailabilitiesWithDates];
    const result = [...baseData];

    // 从状态管理器获取所有持久化状态，覆盖基础数据
    const persistentStates = stateManager.exportAllStates();
    Object.entries(persistentStates).forEach(([roomId, dateStatusMap]) => {
      Object.entries(dateStatusMap).forEach(([date, status]) => {
        const existingIndex = result.findIndex(
          av => av.roomId === roomId && av.month === date
        );

        const newAvailability: RoomAvailability = {
          roomId,
          month: date,
          status,
        };

        if (existingIndex >= 0) {
          // 替换现有状态
          result[existingIndex] = newAvailability;
        } else {
          // 添加新状态
          result.push(newAvailability);
        }
      });
    });

    return result;
  }, [availabilities, mockAvailabilitiesWithDates, stateManager]);

  // 使用优化的数据Hook
  const { filteredRooms } = useOptimizedRoomData(
    rooms,
    allAvailabilities,
    RoomType.ALL
  );

  // 使用简化合并Hook
  const simpleMerge = useSimpleMerge();

  // 动态配置
  const config = useMemo(
    () => ({
      cellWidth: timeAxisState.config.cellWidth,
      cellHeight: 50,
      headerHeight: 60,
      roomNumberWidth: 100,
      roomTypeWidth: 120,
      dates: dateAxisData.dates,
      dateInfos: dateAxisData.dateInfos,
      timeFormat: timeAxisState.config.timeFormat,
    }),
    [dateAxisData, timeAxisState.config]
  );

  // 处理日期导航区域的点击事件
  const handleDateNavigationClick = useCallback(
    (event: React.MouseEvent) => {
      const rect = headerCanvasRef.current?.getBoundingClientRect();
      if (!rect) return;

      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;
      const totalRoomInfoWidth = config.roomTypeWidth + config.roomNumberWidth;

      // 检查是否点击在日期导航区域
      if (
        x >= 0 &&
        x <= totalRoomInfoWidth &&
        y >= 0 &&
        y <= config.headerHeight
      ) {
        // 检查是否点击在左箭头区域 (左侧40px区域)
        if (x >= 0 && x <= 40) {
          // 点击左箭头，向前导航
          console.log('📅 点击左箭头，开始导航');
          try {
            navigateDateRange('prev');
            console.log('📅 左箭头导航完成');
          } catch (error) {
            console.error('左箭头导航失败:', error);
          }
        }
        // 检查是否点击在右箭头区域 (右侧40px区域)
        else if (x >= totalRoomInfoWidth - 40 && x <= totalRoomInfoWidth) {
          // 点击右箭头，向后导航
          console.log('📅 点击右箭头，开始导航');
          try {
            navigateDateRange('next');
            console.log('📅 右箭头导航完成');
          } catch (error) {
            console.error('右箭头导航失败:', error);
          }
        }
      }
    },
    [config, navigateDateRange]
  );

  // 使用悬停效果Hook
  const {
    currentHover,
    handleMouseMove: handleHoverMouseMove,
    handleMouseLeave,
    handleMouseEnter,
    getHoverInfo,
    renderHoverEffects,
    isHoveringCell,
    isHoveringRow,
    isHoveringColumn,
  } = useHoverEffect(filteredRooms, config.dates, config);

  // 使用右键菜单Hook
  const {
    contextMenu,
    showContextMenu,
    hideContextMenu,
    handleContextMenuAction,
  } = useContextMenu((action, room, date, data) => {
    console.log(`🎯 右键菜单操作: ${action}`, {
      room: room.roomNumber,
      date,
      data,
    });

    // 状态管理相关操作 - 显示状态工作流
    if (
      ['status_workflow', 'maintenance', 'available', 'clean'].includes(action)
    ) {
      const availability = allAvailabilities.find(
        av => av.roomId === room.id && av.month === date
      );
      const currentStatus = availability?.status || RoomStatus.AVAILABLE;

      // 显示状态工作流
      setStatusWorkflow({
        visible: true,
        roomId: room.id,
        roomNumber: room.roomNumber,
        date: date,
        currentStatus: currentStatus,
        position: { x: contextMenu.x, y: contextMenu.y },
      });
      return;
    }

    // 简化的操作处理逻辑
    switch (action) {
      case 'book':
        // 新建预订 - 直接更新状态
        updateRoomStatus(room.id, date, RoomStatus.BOOKED);
        break;

      case 'checkin':
        // 办理入住 - 更新为入住状态
        updateRoomStatus(room.id, date, RoomStatus.OCCUPIED);
        break;

      case 'checkout':
        // 办理退房 - 更新为已退房状态
        updateRoomStatus(room.id, date, RoomStatus.CHECKED_OUT);
        break;

      case 'modify':
        // 修改预订 - 记录操作日志
        console.log(`修改预订:`, {
          房间: room.roomNumber,
          日期: date,
          操作: '预订信息修改',
        });
        break;

      case 'cancel':
        // 取消预订 - 直接更新为可用状态
        updateRoomStatus(room.id, date, RoomStatus.AVAILABLE);
        console.log(`预订已取消:`, {
          房间: room.roomNumber,
          日期: date,
        });
        break;

      case 'available':
        // 恢复可用状态 - 从维护/清洁状态恢复
        updateRoomStatus(room.id, date, RoomStatus.AVAILABLE);
        console.log(`房间恢复可用:`, {
          房间: room.roomNumber,
          日期: date,
          操作: '恢复可用状态',
        });
        break;

      case 'clean':
        // 开始清洁
        updateRoomStatus(room.id, date, RoomStatus.CLEANING);
        console.log(`开始清洁:`, {
          房间: room.roomNumber,
          日期: date,
          操作: '房间清洁中',
        });
        break;

      case 'maintenance':
        // 设为维护
        updateRoomStatus(room.id, date, RoomStatus.MAINTENANCE);
        console.log(`设为维护:`, {
          房间: room.roomNumber,
          日期: date,
          操作: '房间维护中',
        });
        break;

      case 'details':
        // 房间详情 - 不显示提示，仅在控制台输出
        console.log(`房间详情:`, {
          房间号: room.roomNumber,
          房型: room.roomType,
          楼层: `${room.floor}楼`,
          价格: `¥${room.price}`,
          日期: date,
          建筑: room.building,
        });
        break;

      case 'merge_suggest': {
        // 打开简化合并面板
        setShowMergePanel(true);
        console.log(`打开合并面板:`, {
          房间: room.roomNumber,
          日期: date,
        });
        break;
      }

      case 'merge_adjacent': {
        // 合并相邻的预订
        const adjacentCells = findAdjacentCells(room.id, date);
        if (adjacentCells.length > 1) {
          simpleMerge.mergeSelectedCells(adjacentCells);
          console.log(`合并相邻预订:`, {
            房间: room.roomNumber,
            合并单元格: adjacentCells.length,
          });
        } else {
          console.log(`没有找到可合并的相邻预订:`, {
            房间: room.roomNumber,
            日期: date,
          });
        }
        break;
      }

      default: {
        // 其他操作 - 直接执行，无确认提示
        const message = data?.message || `执行${action}操作`;
        const actionName = data?.action || action;
        console.log(`操作完成:`, { 操作: actionName, 消息: message });
        break;
      }
    }
  });

  // 拖拽反馈系统
  const { feedbacks, removeFeedback } = useDragOperationFeedback();

  // 拖拽状态通知
  const [dragNotification, setDragNotification] = useState<{
    sourceRoom: Room;
    targetRoom: Room;
    sourceDate: string;
    targetDate: string;
    status: RoomStatus;
    isSuccess: boolean;
  } | null>(null);

  // 使用多选Hook - 提前定义
  const {
    dragSelection,
    isCellSelected,
    getSelectedCount,
    getSelectedCells,
    toggleCellSelection,
    clearSelection,
    startDragSelection,
    updateDragSelection,
    endDragSelection,
    getDragSelectionRange,
  } = useMultiSelection();

  // 长按拖拽Hook
  const longPressDrag = useLongPressDrag({
    delay: 500, // 500ms 长按触发
    threshold: 8, // 8px 移动阈值
  });

  // 房间状态更新函数 - 提前定义
  const updateRoomStatus = useCallback(
    (roomId: string, date: string, newStatus: RoomStatus) => {
      console.log('更新房间状态:', {
        房间ID: roomId,
        日期: date,
        新状态: newStatus,
      });

      // 使用状态管理器更新状态（自动持久化）
      stateManager.setRoomStatus(roomId, date, newStatus);
    },
    [stateManager]
  );

  // 拖拽完成处理函数
  const handleDragComplete = useCallback(
    (
      sourceRoom: Room,
      sourceDate: string,
      targetRoom: Room,
      targetDate: string
    ) => {
      console.log('🎯 拖拽完成:', {
        源房间: sourceRoom.roomNumber,
        源日期: sourceDate,
        目标房间: targetRoom.roomNumber,
        目标日期: targetDate,
      });

      // 获取源房间的状态
      const sourceAvailability = allAvailabilities.find(
        av => av.roomId === sourceRoom.id && av.month === sourceDate
      );
      const sourceStatus = sourceAvailability?.status || RoomStatus.AVAILABLE;

      try {
        // 验证拖拽操作的有效性
        if (!RoomStatusManager.canDrag(sourceStatus)) {
          console.error(
            `${RoomStatusManager.getStatusConfig(sourceStatus).label}状态不允许拖拽`
          );
          return false;
        }

        // 检查目标位置
        const targetAvailability = allAvailabilities.find(
          av => av.roomId === targetRoom.id && av.month === targetDate
        );
        const targetStatus = targetAvailability?.status;

        if (targetStatus && !RoomStatusManager.canDrop(targetStatus)) {
          console.error(
            `目标位置状态为${RoomStatusManager.getStatusConfig(targetStatus).label}，不允许放置`
          );
          return false;
        }

        // 移动状态到目标位置
        updateRoomStatus(targetRoom.id, targetDate, sourceStatus);

        // 清除源位置状态（设为可用）
        if (sourceRoom.id !== targetRoom.id || sourceDate !== targetDate) {
          updateRoomStatus(sourceRoom.id, sourceDate, RoomStatus.AVAILABLE);
        }

        // 检查是否有多个选中的单元格，执行批量移动
        const selectedCells = getSelectedCells();
        if (selectedCells.length > 1) {
          console.log(
            '🎯 检测到多选，执行批量移动，选中数量:',
            selectedCells.length
          );

          const sourceCellKey = `${sourceRoom.id}-${sourceDate}`;
          let successCount = 0;

          selectedCells.forEach(cellKey => {
            if (cellKey !== sourceCellKey) {
              try {
                // 解析其他选中的单元格
                const lastDashIndex = cellKey.lastIndexOf('-');
                const otherRoomId = cellKey.substring(0, lastDashIndex);
                const otherDate = cellKey.substring(lastDashIndex + 1);

                const otherRoom = filteredRooms.find(r => r.id === otherRoomId);
                if (!otherRoom) {
                  console.warn('找不到房间:', otherRoomId);
                  return;
                }

                // 获取其他单元格的状态
                const otherAvailability = allAvailabilities.find(
                  av => av.roomId === otherRoomId && av.month === otherDate
                );
                const otherStatus =
                  otherAvailability?.status || RoomStatus.AVAILABLE;

                // 检查是否可以拖拽
                if (!RoomStatusManager.canDrag(otherStatus)) {
                  console.warn(
                    `${otherRoom.roomNumber}(${otherDate}) 状态不允许拖拽`
                  );
                  return;
                }

                console.log(
                  `📝 移动 ${otherRoom.roomNumber}(${otherDate}) 到 ${targetRoom.roomNumber}(${targetDate})`
                );

                // 移动到目标位置
                updateRoomStatus(targetRoom.id, targetDate, otherStatus);

                // 清除源位置状态
                updateRoomStatus(otherRoomId, otherDate, RoomStatus.AVAILABLE);

                successCount++;
              } catch (error) {
                console.error('批量移动单元格失败:', cellKey, error);
              }
            }
          });

          console.log(`✅ 批量移动完成: ${successCount} 个单元格成功移动`);

          // 清除所有选择
          clearSelection();
        }

        console.log('✅ 拖拽操作成功');

        // 显示成功通知
        setDragNotification({
          sourceRoom,
          targetRoom,
          sourceDate,
          targetDate,
          status: sourceStatus,
          isSuccess: true,
        });

        return true;
      } catch (error) {
        console.error('❌ 拖拽操作失败:', error);

        // 显示失败通知
        setDragNotification({
          sourceRoom,
          targetRoom,
          sourceDate,
          targetDate,
          status: sourceStatus || RoomStatus.AVAILABLE,
          isSuccess: false,
        });

        return false;
      }
    },
    [allAvailabilities, updateRoomStatus]
  );

  // 基础拖拽功能
  const basicDragSystem = useDragDrop(
    filteredRooms,
    config.dates,
    allAvailabilities,
    config,
    handleDragComplete
  );

  // 批量拖拽完成处理
  const handleBatchDragComplete = useCallback(
    (
      operations: Array<{
        sourceRoom: Room;
        sourceDate: string;
        targetRoom: Room;
        targetDate: string;
        status: RoomStatus;
      }>
    ) => {
      console.log('🚀 handleBatchDragComplete 被调用');
      console.log('🎯 批量拖拽完成:', operations);
      console.log('🎯 操作数量:', operations.length);

      let successCount = 0;
      let errorCount = 0;

      operations.forEach((op, index) => {
        console.log(`🔄 执行第 ${index + 1} 个操作:`, op);
        try {
          console.log(
            `📝 设置目标位置: ${op.targetRoom.roomNumber}(${op.targetDate}) = ${op.status}`
          );
          // 移动状态到目标位置
          updateRoomStatus(op.targetRoom.id, op.targetDate, op.status);

          // 清除源位置状态（设为可用）
          if (
            op.sourceRoom.id !== op.targetRoom.id ||
            op.sourceDate !== op.targetDate
          ) {
            console.log(
              `🗑️ 清除源位置: ${op.sourceRoom.roomNumber}(${op.sourceDate}) = AVAILABLE`
            );
            updateRoomStatus(
              op.sourceRoom.id,
              op.sourceDate,
              RoomStatus.AVAILABLE
            );
          }

          console.log(`✅ 第 ${index + 1} 个操作成功`);
          successCount++;
        } catch (error) {
          console.error(`❌ 第 ${index + 1} 个操作失败:`, error);
          errorCount++;
        }
      });

      console.log(`✅ 批量拖拽完成: ${successCount} 成功, ${errorCount} 失败`);

      // 清除选择
      clearSelection();
    },
    [updateRoomStatus, clearSelection]
  );

  // 批量拖拽功能
  const batchDrag = useBatchDragDrop({
    rooms: filteredRooms,
    dates: config.dates,
    availabilities: allAvailabilities,
    selectedCells: getSelectedCells().map(cellKey => {
      // 更安全的解析方式：从末尾找最后一个连字符
      const lastDashIndex = cellKey.lastIndexOf('-');
      if (lastDashIndex === -1) {
        console.error('❌ 无效的cellKey格式:', cellKey);
        return { roomId: '', date: '' };
      }

      const roomId = cellKey.substring(0, lastDashIndex);
      const date = cellKey.substring(lastDashIndex + 1);

      console.log('🔧 解析 cellKey:', { cellKey, roomId, date });
      return { roomId, date };
    }),
    onBatchDragComplete: handleBatchDragComplete,
  });

  // 监听批量拖拽状态变化
  useEffect(() => {
    console.log('🔄 批量拖拽状态变化:', {
      isActive: batchDrag.batchDragState.isActive,
      sourceItemsLength: batchDrag.batchDragState.sourceItems.length,
      previewDataLength: batchDrag.batchDragState.previewData.length,
    });
  }, [batchDrag.batchDragState]);

  // 选择使用的拖拽系统
  const dragSystem = basicDragSystem;
  const { dragState, startDrag, updateDrag, endDrag, renderDragPreview } =
    dragSystem;

  // 单选状态管理
  const [selectedCell, setSelectedCell] = useState<{
    roomId: string;
    date: string;
  } | null>(null);

  // useMultiSelection 已在前面定义

  // 状态选择器状态
  const [statusSelector, setStatusSelector] = useState<{
    visible: boolean;
    roomId: string;
    date: string;
    currentStatus: RoomStatus;
    position: { x: number; y: number };
  } | null>(null);

  // 状态工作流状态
  const [statusWorkflow, setStatusWorkflow] = useState<{
    visible: boolean;
    roomId: string;
    roomNumber: string;
    date: string;
    currentStatus: RoomStatus;
    position: { x: number; y: number };
  } | null>(null);

  // 自定义房间可用性查找
  const getDateRoomAvailability = useCallback(
    (roomId: string, date: string): RoomAvailability | undefined => {
      return allAvailabilities.find(
        av => av.roomId === roomId && av.month === date
      );
    },
    [allAvailabilities]
  );

  // ========== Canvas绘制方法 ==========

  /**
   * 绘制日期单元格
   * 这是甘特图的核心绘制方法，负责绘制每个房间-日期交叉的单元格
   * 包含状态显示、悬停效果、选中状态、合并状态等复杂逻辑
   *
   * @param ctx Canvas 2D渲染上下文
   * @param room 房间信息
   * @param availability 房间可用性信息
   * @param x 单元格X坐标
   * @param y 单元格Y坐标
   * @param date 日期字符串
   * @param dateInfo 日期信息（是否今天、是否周末等）
   * @param roomIndex 房间行索引
   * @param dateIndex 日期列索引
   */
  const drawDateCell = useCallback(
    (
      ctx: CanvasRenderingContext2D,
      room: Room,
      availability: RoomAvailability | undefined,
      x: number,
      y: number,
      date: string,
      dateInfo: {
        isToday: boolean;
        isWeekend: boolean;
        date: string;
        dayOfWeek: string;
      },
      roomIndex: number,
      dateIndex: number
    ) => {
      const isCellHovered = isHoveringCell(roomIndex, dateIndex);
      const isRowHovered = isHoveringRow(roomIndex);
      const isColumnHovered = isHoveringColumn(dateIndex);

      // 检查是否是合并块的一部分
      const mergeBlock = simpleMerge.getMergeBlockForCell(room.id, date);
      const isInMergedBlock = !!mergeBlock;

      // 获取房间状态
      const roomStatus = availability?.status || RoomStatus.AVAILABLE;
      const statusConfig = RoomStatusManager.getStatusConfig(roomStatus);

      // 基础样式使用状态管理器配置
      let backgroundColor = statusConfig.backgroundColor;
      let textColor = statusConfig.color;
      let borderColor = statusConfig.borderColor;
      let text = statusConfig.shortLabel;

      // 特殊显示逻辑
      if (roomStatus === RoomStatus.AVAILABLE) {
        if (dateInfo.isToday) {
          // 今天的可用房间 - 新配色
          backgroundColor = '#cfe2ff';
          borderColor = '#0d6efd';
          text = `今日\n可用\n¥${room.price}`;
          textColor = '#0a58ca';
        } else if (dateInfo.isWeekend) {
          // 周末使用简洁的浅灰配色
          backgroundColor = '#f8f9fa';
          borderColor = '#dee2e6';
          text = `可用\n¥${room.price}`;
          textColor = '#6c757d';
        } else {
          // 平日使用纯净的白色背景
          backgroundColor = '#ffffff';
          borderColor = '#e9ecef';
          text = `可用\n¥${room.price}`;
          textColor = '#6c757d';
        }
      } else {
        // 非可用状态显示房间号、状态和价格
        text = `${room.roomNumber}\n${statusConfig.shortLabel}\n¥${room.price}`;
      }

      // 悬停样式
      if (isCellHovered) {
        backgroundColor = '#fff3e0';
        borderColor = '#ff9800';
        textColor = '#e65100';
      }
      // 移除行悬停高亮效果

      // 合并块特殊处理
      if (isInMergedBlock && mergeBlock) {
        const isFirstCell = mergeBlock.dates[0] === date;

        // 合并块有特殊的样式
        backgroundColor = '#e8f5e8';
        borderColor = '#52c41a';
        textColor = '#2e7d2e';

        // 只在第一个单元格显示完整信息
        if (isFirstCell) {
          const guestInfo = mergeBlock.guestName
            ? `\n${mergeBlock.guestName}`
            : '';
          text = `🔗 ${room.roomNumber}\n${mergeBlock.dates.length}天${guestInfo}`;
        } else {
          text = '···'; // 后续单元格显示省略号
        }
      }

      // 选中状态
      const isSelected =
        selectedCell?.roomId === room.id && selectedCell?.date === date;

      if (isSelected) {
        backgroundColor = '#bbdefb';
        borderColor = '#1976d2';
        textColor = '#0d47a1';
      }

      // 绘制单元格
      ctx.fillStyle = backgroundColor;
      ctx.fillRect(x, y, config.cellWidth, config.cellHeight);

      ctx.strokeStyle = borderColor;
      ctx.lineWidth =
        isCellHovered || isSelected ? 3 : dateInfo.isToday ? 2 : 1;
      ctx.strokeRect(x, y, config.cellWidth, config.cellHeight);

      // 绘制文字
      ctx.fillStyle = textColor;
      ctx.font =
        '10px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';

      if (text.includes('\n')) {
        const lines = text.split('\n');

        if (lines.length === 2) {
          // 两行文本
          ctx.fillText(
            lines[0],
            x + config.cellWidth / 2,
            y + config.cellHeight / 2 - 6
          );
          ctx.font =
            '9px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
          ctx.fillText(
            lines[1],
            x + config.cellWidth / 2,
            y + config.cellHeight / 2 + 6
          );
        } else if (lines.length === 3) {
          // 三行文本（房间号、状态、价格）
          ctx.font =
            '9px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
          ctx.fillText(
            lines[0],
            x + config.cellWidth / 2,
            y + config.cellHeight / 2 - 10
          );
          ctx.fillText(
            lines[1],
            x + config.cellWidth / 2,
            y + config.cellHeight / 2
          );
          // 价格用不同颜色突出显示
          const originalColor = ctx.fillStyle;
          ctx.fillStyle = '#2e7d32'; // 绿色表示收入
          ctx.font =
            'bold 8px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
          ctx.fillText(
            lines[2],
            x + config.cellWidth / 2,
            y + config.cellHeight / 2 + 10
          );
          ctx.fillStyle = originalColor; // 恢复原色
        }
      } else {
        ctx.fillText(text, x + config.cellWidth / 2, y + config.cellHeight / 2);
      }

      // 单选标识
      if (isSelected) {
        ctx.fillStyle = '#1976d2';
        ctx.font =
          'bold 8px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        ctx.fillText('✓', x + config.cellWidth - 6, y + 6);
      }

      // 多选标识（蓝色圆点）
      if (isCellSelected(room.id, date)) {
        ctx.fillStyle = '#0d6efd';
        ctx.beginPath();
        ctx.arc(x + config.cellWidth - 8, y + 8, 4, 0, 2 * Math.PI);
        ctx.fill();

        // 白色勾号
        ctx.fillStyle = '#ffffff';
        ctx.font =
          'bold 6px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('✓', x + config.cellWidth - 8, y + 8);
        ctx.textAlign = 'center'; // 恢复对齐方式
        ctx.textBaseline = 'middle';
      }
    },
    [config, isHoveringCell, isCellSelected, simpleMerge]
  );

  /**
   * 绘制房间行
   * 绘制单个房间的完整行，包括房间信息列和所有日期单元格
   *
   * @param ctx Canvas 2D渲染上下文
   * @param room 房间信息
   * @param y 行Y坐标
   * @param roomIndex 房间行索引
   */
  const drawRoomRow = useCallback(
    (
      ctx: CanvasRenderingContext2D,
      room: Room,
      y: number,
      roomIndex: number
    ) => {
      // 绘制合并的房间信息单元格 (房间类型 + 房间号)
      const totalRoomInfoWidth = config.roomTypeWidth + config.roomNumberWidth;

      // 绘制背景
      ctx.fillStyle = '#f8f9fa';
      ctx.fillRect(0, y, totalRoomInfoWidth, config.cellHeight);

      // 绘制边框
      ctx.strokeStyle = '#e9ecef';
      ctx.lineWidth = 1;
      ctx.strokeRect(0, y, totalRoomInfoWidth, config.cellHeight);

      ctx.fillStyle = '#495057';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';

      const roomTypeLabel = roomTypeLabels[room.roomType] || '未知类型';

      // 房间号 (主要信息，大字体)
      ctx.font =
        'bold 16px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
      ctx.fillText(
        room.roomNumber,
        totalRoomInfoWidth / 2,
        y + config.cellHeight / 2 - 8
      );

      // 房间类型 (次要信息，小字体)
      ctx.font =
        '12px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
      ctx.globalAlpha = 0.7; // 半透明效果
      ctx.fillText(
        roomTypeLabel,
        totalRoomInfoWidth / 2,
        y + config.cellHeight / 2 + 12
      );
      ctx.globalAlpha = 1.0; // 恢复不透明

      // 绘制日期单元格 (可滚动部分)
      config.dates.forEach((date: string, dateIndex: number) => {
        const x =
          config.roomTypeWidth +
          config.roomNumberWidth +
          dateIndex * config.cellWidth;
        const availability = getDateRoomAvailability(room.id, date);
        const dateInfo = config.dateInfos[dateIndex];

        drawDateCell(
          ctx,
          room,
          availability,
          x,
          y,
          date,
          dateInfo,
          roomIndex,
          dateIndex
        );
      });
    },
    [config, getDateRoomAvailability, isHoveringRow, drawDateCell]
  );

  /**
   * 绘制同步滚动表头
   * 绘制甘特图的表头部分，包括房间信息列和日期列
   * 支持同步滚动，确保表头与内容区域保持同步
   */
  const drawSyncHeader = useCallback(() => {
    const headerCanvas = headerCanvasRef.current;
    if (!headerCanvas) return;

    const ctx = headerCanvas.getContext('2d');
    if (!ctx) return;

    const totalWidth =
      config.roomTypeWidth +
      config.roomNumberWidth +
      config.dates.length * config.cellWidth;
    headerCanvas.width = totalWidth;
    headerCanvas.height = config.headerHeight;

    // 清空并绘制表头
    ctx.clearRect(0, 0, totalWidth, config.headerHeight);

    // 表头背景
    ctx.fillStyle = '#f8f9fa';
    ctx.fillRect(0, 0, totalWidth, config.headerHeight);

    // 文字样式
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // 合并的房间信息列标题 (显示日期导航)
    const totalRoomInfoWidth = config.roomTypeWidth + config.roomNumberWidth;

    ctx.fillStyle = '#667eea';
    ctx.fillRect(0, 0, totalRoomInfoWidth, config.headerHeight);

    // 绘制边框
    ctx.strokeStyle = '#5a67d8';
    ctx.lineWidth = 1;
    ctx.strokeRect(0, 0, totalRoomInfoWidth, config.headerHeight);

    ctx.fillStyle = '#ffffff';

    // 获取当前日期 - 使用实际的timeAxisState数据
    let dateText = '';
    if (timeAxisState && timeAxisState.startDate) {
      const currentDate = timeAxisState.startDate;
      const year = currentDate.getFullYear();
      const month = String(currentDate.getMonth() + 1).padStart(2, '0');
      const day = String(currentDate.getDate()).padStart(2, '0');
      dateText = `${year}-${month}-${day} 日`;
    } else {
      // 备用方案：使用今天的日期
      const today = new Date();
      const year = today.getFullYear();
      const month = String(today.getMonth() + 1).padStart(2, '0');
      const day = String(today.getDate()).padStart(2, '0');
      dateText = `${year}-${month}-${day} 日`;
    }

    // 计算日期范围 - 添加安全检查
    let rangeText = '';

    if (config.dates && config.dates.length > 0) {
      try {
        const startDate = config.dates[0];
        const endDate = config.dates[config.dates.length - 1];

        if (
          startDate &&
          endDate &&
          typeof startDate === 'string' &&
          typeof endDate === 'string'
        ) {
          const startParts = startDate.split('-');
          const endParts = endDate.split('-');

          if (startParts.length >= 3 && endParts.length >= 3) {
            const startMonth = startParts[1];
            const startDay = startParts[2];
            const endMonth = endParts[1];
            const endDay = endParts[2];
            rangeText = `${startMonth}/${startDay} - ${endMonth}/${endDay}`;
          }
        }
      } catch (error) {
        console.error('日期范围计算错误:', error);
      }
    }

    // 如果获取失败，生成默认范围
    if (!rangeText) {
      console.warn('使用默认日期范围');
      const today = new Date();
      const endDateCalc = new Date(today);
      endDateCalc.setDate(today.getDate() + 29);
      rangeText = `${String(today.getMonth() + 1).padStart(2, '0')}/${String(today.getDate()).padStart(2, '0')} - ${String(endDateCalc.getMonth() + 1).padStart(2, '0')}/${String(endDateCalc.getDate()).padStart(2, '0')}`;
    }

    // 绘制当前日期 (上半部分)
    ctx.font =
      'bold 12px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(dateText, totalRoomInfoWidth / 2, config.headerHeight / 2 - 8);

    // 绘制左箭头
    ctx.font =
      'bold 14px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('<', 20, config.headerHeight / 2 + 8);

    // 绘制日期范围 (中间)
    ctx.font =
      '10px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
    ctx.globalAlpha = 0.9;
    ctx.fillText(
      rangeText,
      totalRoomInfoWidth / 2,
      config.headerHeight / 2 + 8
    );
    ctx.globalAlpha = 1.0;

    // 绘制右箭头
    ctx.font =
      'bold 14px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
    ctx.fillStyle = '#ffffff';
    ctx.textAlign = 'center';
    ctx.fillText('>', totalRoomInfoWidth - 20, config.headerHeight / 2 + 8);

    // 日期列标题 (可滚动部分)
    config.dateInfos.forEach(
      (
        dateInfo: {
          isToday: boolean;
          isWeekend: boolean;
          date: string;
          dayOfWeek: string;
        },
        index: number
      ) => {
        const x =
          config.roomTypeWidth +
          config.roomNumberWidth +
          index * config.cellWidth;

        // 背景颜色 - 移除悬停高亮
        if (dateInfo.isToday) {
          ctx.fillStyle = '#0d6efd'; // 今天：现代蓝色背景
        } else if (dateInfo.isWeekend) {
          ctx.fillStyle = '#f8f9fa'; // 周末：浅灰背景
        } else {
          ctx.fillStyle = '#ffffff'; // 工作日：纯白背景
        }
        ctx.fillRect(x, 0, config.cellWidth, config.headerHeight);

        // 文字颜色 - 移除悬停高亮
        if (dateInfo.isToday) {
          ctx.fillStyle = '#ffffff'; // 今天：白色文字
        } else if (dateInfo.isWeekend) {
          ctx.fillStyle = '#6c757d'; // 周末：中灰文字
        } else {
          ctx.fillStyle = '#212529'; // 工作日：深色文字
        }

        // 绘制星期和日期
        ctx.font =
          '11px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        const weekText = dateInfo.isToday ? '今天' : dateInfo.dayOfWeek;
        ctx.fillText(
          weekText,
          x + config.cellWidth / 2,
          config.headerHeight / 2 - 8
        );

        ctx.font =
          '10px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        ctx.fillText(
          dateInfo.date,
          x + config.cellWidth / 2,
          config.headerHeight / 2 + 8
        );
      }
    );
  }, [config, isHoveringColumn, timeAxisState]);

  // 绘制内容区域
  /**
   * 主绘制循环
   * 使用双缓冲优化，负责绘制整个甘特图的内容区域
   * 包括所有房间行、悬停效果、选中状态等
   */
  const drawContentArea = useCallback(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    const startTime = performanceUtils.startRenderTimer();

    // 设置内容画布尺寸
    const totalWidth =
      config.roomTypeWidth +
      config.roomNumberWidth +
      config.dates.length * config.cellWidth;
    const contentHeight = filteredRooms.length * config.cellHeight;

    canvas.width = totalWidth;
    canvas.height = contentHeight;

    // 清空画布
    ctx.clearRect(0, 0, totalWidth, contentHeight);

    // 绘制背景
    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, totalWidth, contentHeight);

    // 绘制所有房间
    filteredRooms.forEach((room, index) => {
      const y = index * config.cellHeight;
      drawRoomRow(ctx, room, y, index);
    });

    // 绘制悬停效果
    renderHoverEffects(ctx);

    // 绘制拖拽预览
    renderDragPreview(ctx);

    // 渲染多选拖拽预览
    const dragRange = getDragSelectionRange();
    if (dragRange) {
      const { startRoomIndex, endRoomIndex, startDateIndex, endDateIndex } =
        dragRange;

      const previewX =
        config.roomTypeWidth +
        config.roomNumberWidth +
        startDateIndex * config.cellWidth;
      const previewY = startRoomIndex * config.cellHeight;
      const previewWidth =
        (endDateIndex - startDateIndex + 1) * config.cellWidth;
      const previewHeight =
        (endRoomIndex - startRoomIndex + 1) * config.cellHeight;

      // 绘制选择范围预览
      ctx.save();
      ctx.fillStyle = 'rgba(13, 110, 253, 0.2)'; // 蓝色半透明
      ctx.fillRect(previewX, previewY, previewWidth, previewHeight);

      // 绘制边框
      ctx.strokeStyle = '#0d6efd';
      ctx.lineWidth = 2;
      ctx.setLineDash([5, 5]); // 虚线
      ctx.strokeRect(previewX, previewY, previewWidth, previewHeight);
      ctx.restore();
    }

    const renderTime = performanceUtils.endRenderTimer(startTime);
    console.log(`同步滚动甘特图渲染完成，耗时: ${renderTime.toFixed(2)}ms`);
  }, [
    filteredRooms,
    config,
    renderHoverEffects,
    renderDragPreview,
    getDragSelectionRange,
    drawRoomRow,
  ]);

  // 处理同步滚动
  const handleSyncScroll = useCallback(
    (event: React.UIEvent<HTMLDivElement>) => {
      const container = event.currentTarget;
      const scrollLeft = container.scrollLeft;

      // 同步表头的水平滚动
      if (headerContainerRef.current) {
        headerContainerRef.current.scrollLeft = scrollLeft;
      }

      console.log(`同步滚动: X=${scrollLeft}px`);
    },
    []
  );

  // 处理Canvas鼠标按下（开始拖拽或选择）
  const handleCanvasMouseDown = useCallback(
    (event: React.MouseEvent<HTMLCanvasElement>) => {
      // 只处理左键
      if (event.button !== 0) return;

      const canvas = canvasRef.current;
      if (!canvas) return;

      const rect = canvas.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;

      if (x > config.roomTypeWidth + config.roomNumberWidth) {
        const dateIndex = Math.floor(
          (x - config.roomTypeWidth - config.roomNumberWidth) / config.cellWidth
        );
        const roomIndex = Math.floor(y / config.cellHeight);

        if (
          dateIndex >= 0 &&
          dateIndex < config.dates.length &&
          roomIndex >= 0 &&
          roomIndex < filteredRooms.length
        ) {
          const room = filteredRooms[roomIndex];
          const date = config.dates[dateIndex];

          // 获取房间状态
          const availability = allAvailabilities.find(
            av => av.roomId === room.id && av.month === date
          );
          const roomStatus = availability?.status || RoomStatus.AVAILABLE;

          // 检查是否按住了Ctrl键（多选模式）
          const isMultiSelectMode = event.ctrlKey || event.metaKey;

          // 检查是否有选中的单元格且当前单元格也被选中
          const selectedCount = getSelectedCount();
          const isCurrentCellSelected = isCellSelected(room.id, date);

          console.log('🔍 单元格点击检查:', {
            room: room.roomNumber,
            date,
            selectedCount,
            isCurrentCellSelected,
            isMultiSelectMode,
            roomStatus,
            canDrag: RoomStatusManager.canDrag(roomStatus),
            条件1_多选: selectedCount > 1,
            条件2_当前选中: isCurrentCellSelected,
            条件3_非多选模式: !isMultiSelectMode,
            最终条件:
              selectedCount > 1 && isCurrentCellSelected && !isMultiSelectMode,
          });

          // 如果是多选状态且当前单元格被选中，直接启动批量拖拽
          if (
            selectedCount > 1 &&
            isCurrentCellSelected &&
            !isMultiSelectMode
          ) {
            console.log('🎯 检测到多选状态，直接启动批量拖拽');

            // 直接启动批量拖拽 - 不需要长按
            console.log('🚀 直接触发 - 开始批量拖拽');
            console.log('检查条件:', {
              canStartBatchDrag: batchDrag.canStartBatchDrag,
              selectedCount: getSelectedCount(),
              selectedCells: getSelectedCells(),
            });
            if (batchDrag.canStartBatchDrag) {
              const success = batchDrag.startBatchDrag();
              if (success) {
                console.log('✅ 批量拖拽模式已激活');
                console.log('批量拖拽状态:', batchDrag.batchDragState);
                console.log('🎯 选中的单元格数量:', getSelectedCount());

                // 立即开始常规拖拽，就像单选拖拽一样
                const cellX =
                  config.roomTypeWidth +
                  config.roomNumberWidth +
                  dateIndex * config.cellWidth;
                const cellY = roomIndex * config.cellHeight;
                const rect = canvasRef.current?.getBoundingClientRect();

                if (rect) {
                  const cellBounds = {
                    x: rect.left + cellX,
                    y: rect.top + cellY,
                    width: config.cellWidth,
                    height: config.cellHeight,
                  };

                  console.log('🎯 开始批量拖拽，释放时会移动所有选中的单元格');
                  console.log('🎯 将要批量移动的单元格:', getSelectedCells());
                  startDrag(event, room, date, roomStatus, cellBounds);
                }
              } else {
                console.warn('❌ 无法启动批量拖拽');
              }
            } else {
              console.warn('❌ 不满足启动批量拖拽的条件');
              console.log('🔧 调试信息:', {
                canStartBatchDrag: batchDrag.canStartBatchDrag,
                selectedCount: getSelectedCount(),
                selectedCells: getSelectedCells(),
              });
            }
          } else if (
            RoomStatusManager.canDrag(roomStatus) &&
            !isMultiSelectMode
          ) {
            // 如果是可拖拽的房间且不是多选模式，开始拖拽
            const cellX =
              config.roomTypeWidth +
              config.roomNumberWidth +
              dateIndex * config.cellWidth;
            const cellY = roomIndex * config.cellHeight;
            const cellBounds = {
              x: rect.left + cellX,
              y: rect.top + cellY,
              width: config.cellWidth,
              height: config.cellHeight,
            };

            startDrag(event, room, date, roomStatus, cellBounds);
          } else {
            // 多选逻辑
            const cellData = {
              roomId: room.id,
              date,
              roomIndex,
              dateIndex,
            };

            if (isMultiSelectMode) {
              // Ctrl+点击：切换单个单元格选中状态
              toggleCellSelection(room.id, date);
            } else {
              // 普通点击：开始拖拽选择（如果拖拽）或切换单选
              startDragSelection(cellData);
              setSelectedCell({ roomId: room.id, date });
            }

            if (onRoomSelect) {
              onRoomSelect(room.id, date);
            }

            console.log(`选择房间: ${room.id}, 日期: ${date}`);
          }
        }
      }
    },
    [
      config,
      filteredRooms,
      allAvailabilities,
      onRoomSelect,
      startDrag,
      toggleCellSelection,
      startDragSelection,
      getSelectedCount,
      isCellSelected,
      batchDrag,
      longPressDrag,
    ]
  );

  // 处理Canvas右键点击
  const handleCanvasRightClick = useCallback(
    (event: React.MouseEvent<HTMLCanvasElement>) => {
      const canvas = canvasRef.current;
      if (!canvas) return;

      const rect = canvas.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;

      if (x > config.roomTypeWidth + config.roomNumberWidth) {
        const dateIndex = Math.floor(
          (x - config.roomTypeWidth - config.roomNumberWidth) / config.cellWidth
        );
        const roomIndex = Math.floor(y / config.cellHeight);

        if (
          dateIndex >= 0 &&
          dateIndex < config.dates.length &&
          roomIndex >= 0 &&
          roomIndex < filteredRooms.length
        ) {
          const room = filteredRooms[roomIndex];
          const date = config.dates[dateIndex];

          // 获取房间状态（这里可以根据实际数据来判断）
          const availability = allAvailabilities.find(
            av => av.roomId === room.id && av.month === date
          );
          const roomStatus = availability?.status || RoomStatus.AVAILABLE;

          // 显示右键菜单
          showContextMenu(event, room, date, roomStatus);
        }
      }
    },
    [config, filteredRooms, allAvailabilities, showContextMenu]
  );

  // 综合的鼠标移动处理
  const handleMouseMove = useCallback(
    (event: React.MouseEvent<HTMLCanvasElement>) => {
      // 如果正在拖拽预订，更新拖拽状态
      if (dragState.isDragging) {
        updateDrag(event);
      } else if (dragSelection.isSelecting) {
        // 如果正在拖拽选择，更新选择范围
        const canvas = canvasRef.current;
        if (!canvas) return;

        const rect = canvas.getBoundingClientRect();
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;

        if (x > config.roomTypeWidth + config.roomNumberWidth) {
          const dateIndex = Math.floor(
            (x - config.roomTypeWidth - config.roomNumberWidth) /
              config.cellWidth
          );
          const roomIndex = Math.floor(y / config.cellHeight);

          if (
            dateIndex >= 0 &&
            dateIndex < config.dates.length &&
            roomIndex >= 0 &&
            roomIndex < filteredRooms.length
          ) {
            const room = filteredRooms[roomIndex];
            const date = config.dates[dateIndex];

            updateDragSelection({
              roomId: room.id,
              date,
              roomIndex,
              dateIndex,
            });
          }
        }
      } else {
        // 否则处理悬停效果
        handleHoverMouseMove(event);
      }
    },
    [
      dragState.isDragging,
      dragSelection.isSelecting,
      updateDrag,
      updateDragSelection,
      handleHoverMouseMove,
      config,
      filteredRooms,
    ]
  );

  // 处理鼠标释放
  const handleMouseUp = useCallback(() => {
    if (dragState.isDragging) {
      endDrag();
    } else if (dragSelection.isSelecting) {
      endDragSelection(filteredRooms, config.dates);
    }
  }, [
    dragState.isDragging,
    dragSelection.isSelecting,
    endDrag,
    endDragSelection,
    filteredRooms,
    config.dates,
  ]);

  // 处理新建订单
  const handleNewOrder = useCallback(() => {
    if (selectedCell && onNewOrder) {
      onNewOrder(selectedCell.roomId, selectedCell.date);
    } else {
      console.log('请先选择房间和日期');
    }
  }, [selectedCell, onNewOrder]);

  // 删除重复的 handleCanvasMouseDown 定义，使用已有的版本

  // 查找相邻的可合并单元格
  const findAdjacentCells = useCallback(
    (roomId: string, centerDate: string) => {
      const centerIndex = config.dates.indexOf(centerDate);
      if (centerIndex === -1) return [];

      const adjacentCells: { roomId: string; date: string }[] = [];
      const roomAvailabilities = allAvailabilities.filter(
        av => av.roomId === roomId
      );

      // 获取中心单元格的状态
      const centerAvailability = roomAvailabilities.find(
        av => av.month === centerDate
      );
      if (
        !centerAvailability ||
        ![
          RoomStatus.BOOKED as string,
          RoomStatus.OCCUPIED as string,
          RoomStatus.VIP_BOOKED as string,
        ].includes(centerAvailability.status as string)
      ) {
        return [{ roomId, date: centerDate }];
      }

      const targetStatus = centerAvailability.status;
      adjacentCells.push({ roomId, date: centerDate });

      // 向左查找连续的相同状态
      for (let i = centerIndex - 1; i >= 0; i--) {
        const date = config.dates[i];
        const availability = roomAvailabilities.find(av => av.month === date);
        if (availability && availability.status === targetStatus) {
          adjacentCells.unshift({ roomId, date });
        } else {
          break;
        }
      }

      // 向右查找连续的相同状态
      for (let i = centerIndex + 1; i < config.dates.length; i++) {
        const date = config.dates[i];
        const availability = roomAvailabilities.find(av => av.month === date);
        if (availability && availability.status === targetStatus) {
          adjacentCells.push({ roomId, date });
        } else {
          break;
        }
      }

      return adjacentCells;
    },
    [config.dates, allAvailabilities]
  );

  // updateRoomStatus 已在前面定义

  // 处理状态变更
  const handleStatusChange = useCallback(
    (newStatus: RoomStatus) => {
      if (!statusSelector) return;

      // 使用updateRoomStatus函数来更新状态
      updateRoomStatus(statusSelector.roomId, statusSelector.date, newStatus);

      // 在控制台输出状态变更信息
      const statusConfig = RoomStatusManager.getStatusConfig(newStatus);
      const room = filteredRooms.find(r => r.id === statusSelector.roomId);
      console.log(`状态更新成功:`, {
        房间: room?.roomNumber,
        日期: statusSelector.date,
        新状态: `${statusConfig.icon} ${statusConfig.label}`,
      });

      setStatusSelector(null);
    },
    [statusSelector, filteredRooms, updateRoomStatus]
  );

  // 关闭状态选择器
  const handleCloseStatusSelector = useCallback(() => {
    setStatusSelector(null);
  }, []);

  // 关闭状态工作流
  const handleCloseStatusWorkflow = useCallback(() => {
    setStatusWorkflow(null);
  }, []);

  // 处理工作流状态变更
  const handleWorkflowStatusChange = useCallback(
    (newStatus: RoomStatus, reason?: string) => {
      if (!statusWorkflow) return;

      // 使用updateRoomStatus函数来更新状态
      updateRoomStatus(statusWorkflow.roomId, statusWorkflow.date, newStatus);

      // 在控制台输出状态变更信息
      const statusConfig = RoomStatusManager.getStatusConfig(newStatus);
      console.log(`状态工作流更新:`, {
        房间: statusWorkflow.roomNumber,
        日期: statusWorkflow.date,
        新状态: `${statusConfig.icon} ${statusConfig.label}`,
        原因: reason || '无',
      });

      setStatusWorkflow(null);
    },
    [statusWorkflow, updateRoomStatus]
  );

  // 处理新增订单
  const handleCreateOrder = useCallback(
    (orderData: OrderFormData) => {
      console.log('🎯 创建新订单:', orderData);

      try {
        // 更新房间状态为已预订
        if (orderData.selectedRoomId && orderData.checkInDate) {
          // 计算预订期间的所有日期
          const checkIn = new Date(orderData.checkInDate);
          const checkOut = new Date(orderData.checkOutDate);
          const dates = [];

          for (
            let d = new Date(checkIn);
            d < checkOut;
            d.setDate(d.getDate() + 1)
          ) {
            const dateStr = `${(d.getMonth() + 1).toString().padStart(2, '0')}/${d.getDate().toString().padStart(2, '0')}`;
            dates.push(dateStr);
          }

          // 批量更新房间状态
          dates.forEach(date => {
            stateManager.setRoomStatus(
              orderData.selectedRoomId,
              date,
              RoomStatus.BOOKED
            );
          });

          console.log('✅ 订单创建成功', {
            房间: orderData.selectedRoomId,
            客人: orderData.guestName,
            入住日期: orderData.checkInDate,
            退房日期: orderData.checkOutDate,
            影响日期: dates,
            总金额: orderData.totalAmount,
          });
        }
      } catch (error) {
        console.error('❌ 订单创建失败:', error);
      }
    },
    [stateManager]
  );

  // 打开新增订单抽屉
  const openOrderDrawer = useCallback((roomId?: string, date?: string) => {
    setSelectedCellForOrder(roomId && date ? { roomId, date } : null);
    setShowOrderDrawer(true);
  }, []);

  const handleBatchOperation = useCallback(
    async (
      operation: BatchOperation,
      cells: {
        roomId: string;
        date: string;
        roomIndex: number;
        dateIndex: number;
      }[]
    ) => {
      try {
        console.log(`🎯 开始批量操作: ${operation.label}`, {
          操作类型: operation.id,
          目标状态: operation.targetStatus,
          影响单元格: cells.length,
        });

        // 执行批量操作
        const result = await batchOperations.executeBatchOperation(
          operation,
          cells,
          filteredRooms
        );

        if (result.success) {
          console.log(`✅ 批量操作成功完成`, {
            更新数量: result.updatedCount,
            跳过数量: result.skippedCount,
            操作: operation.label,
          });

          // 清空选择（可选）
          clearSelection();

          // 记录成功信息（无弹框）
          if (result.updatedCount > 0) {
            console.log(`✅ 批量操作完成！`, {
              成功更新: result.updatedCount,
              跳过: result.skippedCount,
              操作: operation.label,
            });
          }
        } else {
          console.error(`❌ 批量操作失败`, result.errors);
          console.error(`批量操作失败详情:`, result.errors.join(', '));
        }

        return result;
      } catch (error) {
        console.error('批量操作异常:', error);
        console.error(`批量操作发生异常: ${error}`);
        throw error;
      }
    },
    [batchOperations, filteredRooms, clearSelection]
  );

  // 绘制表头
  useEffect(() => {
    drawSyncHeader();
  }, [drawSyncHeader]);

  // 绘制内容
  useEffect(() => {
    drawContentArea();
  }, [drawContentArea]);

  // 计算内容高度
  const contentHeight = filteredRooms.length * config.cellHeight;

  return (
    <div className={styles.ganttContainer}>
      {/* 头部 */}
      <div className={styles.ganttHeader}>
        <h1 className={styles.ganttTitle}>房态</h1>
        <div className={styles.headerActions}>
          <span
            style={{ fontSize: '12px', color: '#666', marginRight: '16px' }}
          >
            📅 {timeAxisState.config.title} | {config.dates.length}个时间单位
          </span>

          {/* 拖拽系统切换 */}
          <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
            <label style={{ fontSize: '12px', color: '#666' }}>
              <input
                type='checkbox'
                checked={useEnhancedDrag}
                onChange={e => setUseEnhancedDrag(e.target.checked)}
                style={{ marginRight: '4px' }}
              />
              增强拖拽
            </label>
          </div>
          <button
            className={styles.newOrderBtn}
            onClick={handleNewOrder}
            disabled={!selectedCell}
          >
            <span className={styles.plusIcon}>+</span>
            新建订单
          </button>
          <div className={styles.userAvatar}>
            <div className={styles.avatarCircle}>用</div>
          </div>
        </div>
      </div>

      {/* 批量拖拽工具栏 */}
      <BatchDragToolbar
        isActive={batchDrag.batchDragState.isActive}
        stats={{
          ...batchDrag.getBatchDragStats(),
          canComplete: batchDrag.getBatchDragStats().canComplete ?? false,
        }}
        onStart={() => {
          if (batchDrag.canStartBatchDrag) {
            const success = batchDrag.startBatchDrag();
            if (!success) {
              console.warn('无法开始批量拖拽：没有有效的选中项');
            }
          } else {
            console.warn('无法开始批量拖拽：没有有效的选中项');
          }
        }}
        onComplete={batchDrag.completeBatchDrag}
        onCancel={batchDrag.cancelBatchDrag}
        disabled={!batchDrag.canStartBatchDrag}
      />

      {/* 多选信息面板 */}
      {getSelectedCount() > 0 && (
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: '12px',
            padding: '8px 16px',
            background: '#cfe2ff',
            border: '1px solid #0d6efd',
            borderRadius: '6px',
            margin: '8px 0',
          }}
        >
          <span
            style={{
              color: '#0a58ca',
              fontWeight: 600,
              fontSize: '14px',
            }}
          >
            🎯 已选中 {getSelectedCount()} 个单元格
          </span>
          <button
            onClick={clearSelection}
            style={{
              background: '#0d6efd',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              padding: '4px 8px',
              fontSize: '12px',
              cursor: 'pointer',
              fontWeight: 600,
              marginRight: '8px',
            }}
          >
            清空选择
          </button>
          <button
            onClick={() => openOrderDrawer()}
            style={{
              background: '#52c41a',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              padding: '4px 8px',
              fontSize: '12px',
              cursor: 'pointer',
              fontWeight: 600,
              marginRight: '8px',
              transition: 'all 0.2s ease',
              display: 'flex',
              alignItems: 'center',
              gap: '4px',
            }}
            onMouseEnter={e => {
              e.currentTarget.style.backgroundColor = '#73d13d';
            }}
            onMouseLeave={e => {
              e.currentTarget.style.backgroundColor = '#52c41a';
            }}
          >
            <span>📝</span>
            新增订单
          </button>

          <button
            onClick={() => {
              if (getSelectedCount() > 0) {
                // 调试信息：显示选中的单元格信息
                const selectedCells = getSelectedCells();
                console.log('🎯 准备批量操作:', {
                  选中单元格数量: selectedCells.length,
                  选中的cellKeys: selectedCells,
                  解析后的房间信息: selectedCells.map(cellKey => {
                    const lastDashIndex = cellKey.lastIndexOf('-');
                    const roomId = cellKey.substring(0, lastDashIndex);
                    const date = cellKey.substring(lastDashIndex + 1);
                    const room = filteredRooms.find(r => r.id === roomId);
                    return {
                      cellKey,
                      roomId,
                      date,
                      roomFound: !!room,
                      roomNumber: room?.roomNumber,
                    };
                  }),
                });

                setShowBatchMenu(true);
              } else {
                console.log('请先选择要操作的单元格');
              }
            }}
            style={{
              background: getSelectedCount() > 0 ? '#2196f3' : '#ccc',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              padding: '4px 8px',
              fontSize: '12px',
              cursor: getSelectedCount() > 0 ? 'pointer' : 'not-allowed',
              fontWeight: 600,
              marginRight: '8px',
              transition: 'all 0.2s ease',
            }}
            disabled={getSelectedCount() === 0}
          >
            🎯 批量操作 ({getSelectedCount()})
          </button>
          <button
            onClick={() => setShowMergePanel(true)}
            style={{
              background: '#9c27b0',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              padding: '4px 8px',
              fontSize: '12px',
              cursor: 'pointer',
              fontWeight: 600,
              marginRight: '8px',
              transition: 'all 0.2s ease',
            }}
          >
            🔗 合并管理 ({simpleMerge.mergedBlocks.length})
          </button>
          <button
            onClick={() => setShowDebugPanel(!showDebugPanel)}
            style={{
              background: showDebugPanel ? '#f44336' : '#4caf50',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              padding: '4px 8px',
              fontSize: '12px',
              cursor: 'pointer',
              fontWeight: 600,
            }}
          >
            {showDebugPanel ? '🔧 关闭调试' : '🔧 状态调试'}
          </button>
        </div>
      )}

      {/* 悬停信息提示 */}
      {currentHover && (
        <div
          style={{
            position: 'fixed',
            top: '10px',
            left: '50%',
            transform: 'translateX(-50%)',
            background: 'rgba(0, 0, 0, 0.8)',
            color: 'white',
            padding: '8px 16px',
            borderRadius: '6px',
            fontSize: '13px',
            fontWeight: '500',
            zIndex: 1000,
            boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',
            pointerEvents: 'none',
          }}
        >
          <div style={{ textAlign: 'center' }}>{getHoverInfo()}</div>
        </div>
      )}

      {/* 同步滚动Canvas甘特图 */}
      <div
        className={styles.canvasContainer}
        style={{
          flex: 1,
          minHeight: 0,
          position: 'relative',
          display: 'flex',
          flexDirection: 'column',
        }}
      >
        {/* 表头：Y轴固定，X轴可滚动 */}
        <div
          ref={headerContainerRef}
          style={{
            position: 'relative',
            zIndex: 10,
            background: '#fff',
            borderBottom: '2px solid #e0e0e0',
            flexShrink: 0,
            overflowX: 'hidden', // 通过同步控制水平滚动
            overflowY: 'hidden', // 垂直方向固定
            width: '100%',
          }}
        >
          <canvas
            ref={headerCanvasRef}
            onClick={handleDateNavigationClick}
            style={{
              display: 'block',
              cursor: 'pointer',
            }}
          />
        </div>

        {/* 内容：双向滚动，与表头X轴同步 */}
        <div
          ref={containerRef}
          style={{
            flex: 1,
            overflow: 'auto', // 支持双向滚动
            position: 'relative',
          }}
          onScroll={handleSyncScroll}
        >
          <div
            style={{
              width: `${config.roomTypeWidth + config.roomNumberWidth + config.dates.length * config.cellWidth}px`,
              height: `${contentHeight}px`,
              position: 'relative',
            }}
          >
            <canvas
              ref={canvasRef}
              onMouseDown={handleCanvasMouseDown}
              onContextMenu={handleCanvasRightClick}
              onMouseMove={e => {
                // 批量拖拽模式下使用相同的鼠标移动处理
                handleMouseMove(e);
              }}
              onMouseUp={e => {
                // 批量拖拽模式下使用相同的鼠标释放处理
                if (batchDrag.batchDragState.isActive) {
                  // 在批量拖拽模式下，拦截endDrag并执行批量操作
                  console.log('🎯 批量拖拽模式下的鼠标释放');
                  const dragEndResult = endDrag();

                  // 如果有拖拽数据，执行批量操作
                  if (dragState.dragData) {
                    console.log('🎯 执行批量拖拽完成操作');
                    console.log('🎯 拖拽目标:', {
                      targetRoom: dragState.dragData.targetRoom.roomNumber,
                      targetDate: dragState.dragData.targetDate,
                    });
                    console.log(
                      '🎯 当前批量拖拽状态:',
                      batchDrag.batchDragState
                    );

                    // 获取所有选中的单元格并移动到拖拽目标位置
                    const selectedCells = getSelectedCells();
                    console.log('🎯 选中的单元格:', selectedCells);
                    console.log(
                      '🎯 批量拖拽源项目:',
                      batchDrag.batchDragState.sourceItems
                    );

                    const operations = selectedCells
                      .map(cellKey => {
                        const lastDashIndex = cellKey.lastIndexOf('-');
                        const roomId = cellKey.substring(0, lastDashIndex);
                        const date = cellKey.substring(lastDashIndex + 1);

                        const sourceRoom = filteredRooms.find(
                          r => r.id === roomId
                        );
                        const sourceAvailability = allAvailabilities.find(
                          av => av.roomId === roomId && av.month === date
                        );

                        console.log('🎯 创建操作:', {
                          from: `${sourceRoom?.roomNumber}(${date})`,
                          to: `${dragState.dragData!.targetRoom.roomNumber}(${dragState.dragData!.targetDate})`,
                          status: sourceAvailability?.status,
                        });

                        return {
                          sourceRoom: sourceRoom!,
                          sourceDate: date,
                          targetRoom: dragState.dragData!.targetRoom,
                          targetDate: dragState.dragData!.targetDate,
                          status:
                            sourceAvailability?.status || RoomStatus.AVAILABLE,
                        };
                      })
                      .filter(op => op.sourceRoom);

                    console.log('🎯 总共要执行的操作数量:', operations.length);
                    console.log('🎯 详细操作列表:', operations);

                    // 执行批量拖拽完成回调
                    console.log('🚀 调用 handleBatchDragComplete');
                    handleBatchDragComplete(operations);

                    // 取消批量拖拽模式
                    batchDrag.cancelBatchDrag();
                  } else {
                    console.warn('❌ 没有拖拽数据，无法执行批量操作');
                  }
                } else {
                  handleMouseUp(e);
                }
              }}
              onMouseLeave={() => {
                // 统一处理鼠标离开事件
                handleMouseLeave();
                if (batchDrag.batchDragState.isActive) {
                  batchDrag.cancelBatchDrag();
                }
              }}
              onMouseEnter={handleMouseEnter}
              className={styles.ganttCanvas}
              style={{
                position: 'absolute',
                top: 0,
                left: 0,
                cursor: dragState.isDragging
                  ? dragState.canDrop
                    ? 'grabbing'
                    : 'not-allowed'
                  : batchDrag.batchDragState.isActive
                    ? 'move'
                    : 'pointer',
              }}
            />
          </div>
        </div>
      </div>

      {/* 操作说明 */}
      <div
        style={{
          fontSize: '11px',
          color: '#666',
          padding: '8px',
          background: '#f9f9f9',
          borderRadius: '4px',
          margin: '8px 0',
          textAlign: 'center',
        }}
      >
        💡 操作提示: 鼠标悬停预览 | Y轴滚动查看更多房间 | X轴滚动查看更多日期 |
        左键选择房间 | Ctrl+左键多选 | 拖拽范围选择 | 右键菜单操作 |
        拖拽已预订房间移动 |{' '}
        <span style={{ color: '#0d6efd', fontWeight: 'bold' }}>
          蓝色=今天/多选
        </span>{' '}
        |<span style={{ color: '#6c757d' }}>灰色=周末</span>
      </div>

      {/* 右键菜单 */}
      <ContextMenu
        visible={contextMenu.visible}
        x={contextMenu.x}
        y={contextMenu.y}
        room={contextMenu.room}
        date={contextMenu.date}
        roomStatus={contextMenu.roomStatus}
        onClose={hideContextMenu}
        onAction={handleContextMenuAction}
      />

      {/* 拖拽预览 */}
      {useEnhancedDrag ? (
        <EnhancedDragPreview dragState={dragSystem.dragState} config={config} />
      ) : (
        <DragPreview dragState={dragSystem.dragState} config={config} />
      )}

      {/* 拖拽操作反馈 */}
      <DragOperationFeedback
        feedbacks={feedbacks}
        onRemoveFeedback={removeFeedback}
        position='top-right'
        maxVisible={3}
      />

      {/* 拖拽状态通知 */}
      {dragNotification && (
        <DragStatusNotification
          sourceRoom={dragNotification.sourceRoom}
          targetRoom={dragNotification.targetRoom}
          sourceDate={dragNotification.sourceDate}
          targetDate={dragNotification.targetDate}
          status={dragNotification.status}
          isSuccess={dragNotification.isSuccess}
          onClose={() => setDragNotification(null)}
        />
      )}

      {/* 批量拖拽可视化 */}
      {console.log('🎨 渲染 BatchDragVisualizer:', {
        isActive: batchDrag.batchDragState.isActive,
        sourceItemsLength: batchDrag.batchDragState.sourceItems.length,
        previewDataLength: batchDrag.batchDragState.previewData.length,
      })}
      <BatchDragVisualizer
        batchDragState={batchDrag.batchDragState}
        config={config}
        rooms={filteredRooms}
        dates={config.dates}
      />

      {/* 长按指示器 */}
      <LongPressIndicator
        longPressState={longPressDrag.longPressState}
        progress={longPressDrag.getLongPressProgress()}
        config={config}
        selectedCount={getSelectedCount()}
      />

      {/* 状态选择器 */}
      {statusSelector && (
        <StatusSelector
          currentStatus={statusSelector.currentStatus}
          onStatusChange={handleStatusChange}
          onClose={handleCloseStatusSelector}
          position={statusSelector.position}
          roomNumber={
            filteredRooms.find(r => r.id === statusSelector.roomId)?.roomNumber
          }
        />
      )}

      {/* 状态工作流 */}
      {statusWorkflow && (
        <StatusWorkflow
          currentStatus={statusWorkflow.currentStatus}
          roomId={statusWorkflow.roomId}
          roomNumber={statusWorkflow.roomNumber}
          date={statusWorkflow.date}
          onStatusChange={handleWorkflowStatusChange}
          onClose={handleCloseStatusWorkflow}
          position={statusWorkflow.position}
        />
      )}

      {/* 状态管理器调试面板 */}
      <StateManagerDebugPanel
        visible={showDebugPanel}
        onClose={() => setShowDebugPanel(false)}
      />

      {/* 批量拖拽可视化 */}
      <BatchDragVisualizer
        batchDragState={batchDrag.batchDragState}
        config={config}
        rooms={filteredRooms}
        dates={config.dates}
      />

      {/* 长按指示器 */}
      <LongPressIndicator
        longPressState={longPressDrag.longPressState}
        progress={longPressDrag.getLongPressProgress()}
        config={config}
        selectedCount={getSelectedCount()}
      />

      {/* 批量操作菜单 */}
      <BatchOperationMenu
        visible={showBatchMenu}
        selectedCount={getSelectedCount()}
        selectedCells={getSelectedCells()
          .map((cellKey: string) => {
            // 更安全的解析方式：从末尾找最后一个连字符
            const lastDashIndex = cellKey.lastIndexOf('-');
            if (lastDashIndex === -1) {
              console.error('无效的cellKey格式:', cellKey);
              return { roomId: '', date: '', roomIndex: -1, dateIndex: -1 };
            }

            const roomId = cellKey.substring(0, lastDashIndex);
            const date = cellKey.substring(lastDashIndex + 1);
            const roomIndex = filteredRooms.findIndex(r => r.id === roomId);
            const dateIndex = config.dates.findIndex(d => d === date);

            if (roomIndex === -1) {
              console.error('未找到房间:', {
                roomId,
                cellKey,
                availableRooms: filteredRooms.map(r => r.id),
              });
            }
            if (dateIndex === -1) {
              console.error('未找到日期:', {
                date,
                cellKey,
                availableDates: config.dates,
              });
            }

            return { roomId, date, roomIndex, dateIndex };
          })
          .filter(cell => cell.roomIndex !== -1 && cell.dateIndex !== -1)}
        rooms={filteredRooms}
        onClose={() => setShowBatchMenu(false)}
        onBatchOperation={handleBatchOperation}
      />

      <OrderDrawer
        visible={showOrderDrawer}
        onClose={() => setShowOrderDrawer(false)}
        onSubmit={handleCreateOrder}
        rooms={filteredRooms}
        selectedRoomId={selectedCellForOrder?.roomId}
        selectedDate={selectedCellForOrder?.date}
        availableRooms={filteredRooms.filter(() => {
          // 过滤出可用房间（这里可以添加更复杂的逻辑）
          return true;
        })}
      />

      {/* 简化合并面板 */}
      <SimpleMergePanel
        visible={showMergePanel}
        mergedBlocks={simpleMerge.mergedBlocks}
        selectedCells={getSelectedCells().map((cellKey: string) => {
          const lastDashIndex = cellKey.lastIndexOf('-');
          const roomId = cellKey.substring(0, lastDashIndex);
          const date = cellKey.substring(lastDashIndex + 1);
          return { roomId, date };
        })}
        rooms={filteredRooms}
        stats={simpleMerge.getStats()}
        onClose={() => setShowMergePanel(false)}
        onMergeSelected={(guestName, note) => {
          const selectedCells = getSelectedCells().map((cellKey: string) => {
            const lastDashIndex = cellKey.lastIndexOf('-');
            const roomId = cellKey.substring(0, lastDashIndex);
            const date = cellKey.substring(lastDashIndex + 1);
            return { roomId, date };
          });
          simpleMerge.mergeSelectedCells(selectedCells, guestName, note);
          clearSelection(); // 合并后清空选择
        }}
        onSplitBlock={simpleMerge.splitMergedBlock}
        onUpdateBlock={simpleMerge.updateMergedBlock}
        onClearAll={simpleMerge.clearAllMerges}
      />
    </div>
  );
};

export default SyncScrollGanttChart;
